package com.feishu.json.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.math.BigInteger;
import java.time.Instant;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ConstructionHttpClientJsonUtils {
    /**
     * 自动获取BigInteger类型id
     * @return
     */
    public static BigInteger generateUniqueId() {
        long timestamp = Instant.now().toEpochMilli();
        long sequence = System.nanoTime() % 1000000;

        String idStr = timestamp + "" + 1 + "" + sequence;
        return new BigInteger(idStr);
    }

    public static void setInTree(List<Map<String, Object>> settingList,Object parameter,Map<String,Object> keyValue) throws Exception{

        Map<String,Object> inTree=new HashMap<>();
        setParameterToTree(settingList,"0",inTree);
        Map<String,Object> inTreeData=new HashMap<>();
        JSONObject obj=null;
        if(parameter instanceof String){
            obj=JSONObject.parseObject((String) parameter);
        }
        else if(parameter instanceof JSONObject){
            obj= (JSONObject) parameter;
        }
        else if(parameter instanceof Map){
            obj= JSONObject.parseObject(JSONObject.toJSONString(parameter));
        }
        else{
            obj= JSONObject.parseObject(JSONObject.toJSONString(parameter));
        }


        getInTreeData(inTree,inTreeData,obj,keyValue);

    }
    private static void setParameterToTree(List<Map<String, Object>> list,String parentId,Map<String,Object> entity){
        for(int i=0;i<list.size();i++){
            Map<String, Object> map=list.get(i);
            if(parentId.equals(map.get("parent_id"))){
                entity.put((String) map.get("node"),map);
                setParameterToTree(list,(String) map.get("id"),map);
            }
        }
    }
    private static void getInTreeData(Map<String,Object> tree,Object mapOrList,Object jsonParameter,Map<String,Object> keyValue){
        Set<Map.Entry<String,Object>> set=tree.entrySet();
        for(Map.Entry<String,Object> entity: set) {
            if(entity.getValue() instanceof Map){
                Map<String,Object> entityMap= (Map<String, Object>) entity.getValue();
                int valuation_type= -2;
                if(entityMap.get("valuation_type")!=null){
                    valuation_type= (int) entityMap.get("valuation_type");
                }
                int data_type=-2;
                if(entityMap.get("data_type")!=null){
                    data_type= (int) entityMap.get("data_type");
                }
                String node_key= (String) entityMap.get("node_key");
                String default_value= (String) entityMap.get("default_value");
                String node= (String) entityMap.get("node");

                if(valuation_type==0){
                    if(data_type==-2){
                        if(mapOrList instanceof Map){
                            List entityList=new ArrayList();
                            ((Map<String,Object>)mapOrList).put(entity.getKey(),entityList);
                            keyValue.put(node_key,entityList);

                            Map<String,Object> childMap=new HashMap<>();
                            entityList.add(childMap);
                            if(jsonParameter instanceof JSONObject){
                                getInTreeData(entityMap,childMap,((JSONObject)jsonParameter).get(entity.getKey()),keyValue);
                            }
                            else if(jsonParameter instanceof JSONArray){
                                getInTreeData(entityMap,childMap,jsonParameter,keyValue);
                            }

                        }
                    }
                    else if(data_type==-1){
                        if(mapOrList instanceof Map){
                            List entityList=new ArrayList();
                            ((Map<String,Object>)mapOrList).put(entity.getKey(),entityList);
                            keyValue.put(node_key,entityList);

                            Map<String,Object> childMap=new HashMap<>();
                            entityList.add(childMap);
                            if(jsonParameter instanceof JSONObject){
                                getInTreeData(entityMap,childMap,((JSONObject)jsonParameter).get(entity.getKey()),keyValue);
                            }
                            else if(jsonParameter instanceof JSONArray){
                                getInTreeData(entityMap,childMap,jsonParameter,keyValue);
                            }

                        }
                    }
                    else if(data_type==0){
                        Map<String,Object> childMap=new HashMap<>();
                        ((Map<String,Object>)mapOrList).put(entity.getKey(),childMap);
                        keyValue.put(node_key,childMap);
                        if(jsonParameter instanceof JSONObject){
                            getInTreeData(entityMap,childMap,((JSONObject)jsonParameter).get(entity.getKey()),keyValue);
                        }
                        else if(jsonParameter instanceof JSONArray){
                        }
                    }
                }
                else if(valuation_type== 1){

                    if(mapOrList instanceof Map){
                        if(data_type==5){
                            if(default_value==null){
                                ((Map<String,Object>)mapOrList).put(entity.getKey(),null);
                            }
                            else{
                                JSONObject v=JSONObject.parseObject(default_value);
                                keyValue.put(node_key,v.get("value"));
                                ((Map<String,Object>)mapOrList).put(entity.getKey(),v.get("value"));
                            }
                        }
                        else if(data_type==4){
                            if(default_value==null){
                                ((Map<String,Object>)mapOrList).put(entity.getKey(),null);
                            }
                            else{
                                JSONObject v=JSONObject.parseObject(default_value);
                                keyValue.put(node_key,v.getDoubleValue("value"));
                                ((Map<String,Object>)mapOrList).put(entity.getKey(),v.getDoubleValue("value"));
                            }
                        }
                        else{
                            if(default_value==null){
                                ((Map<String,Object>)mapOrList).put(entity.getKey(),null);
                            }
                            else{
                                JSONObject v=JSONObject.parseObject(default_value);
                                keyValue.put(node_key,v.get("value"));
                                ((Map<String,Object>)mapOrList).put(entity.getKey(),v.get("value"));
                            }
                        }
                    }
                    else if(mapOrList instanceof List){

                    }
                }
                else if(valuation_type==2){
                    if(mapOrList instanceof Map){
                        if(data_type==5){
                            if(jsonParameter==null){
                                ((Map<String,Object>)mapOrList).put(entity.getKey(),null);
                            }
                            else{
                                if(jsonParameter instanceof JSONObject){
                                    keyValue.put(node_key,((JSONObject)jsonParameter).get(entity.getKey()));
                                    ((Map<String,Object>)mapOrList).put(entity.getKey(),((JSONObject)jsonParameter).get(entity.getKey()));
                                }
                                else if(jsonParameter instanceof JSONArray){
                                    keyValue.put(node_key,((JSONArray)jsonParameter).getJSONObject(0).get(entity.getKey()));
                                    ((Map<String,Object>)mapOrList).put(entity.getKey(),((JSONArray)jsonParameter).getJSONObject(0).get(entity.getKey()));
                                }
                            }
                        }
                        else if(data_type==4){
                            if(jsonParameter==null){
                                ((Map<String,Object>)mapOrList).put(entity.getKey(),null);
                            }
                            else{
                                if(jsonParameter instanceof JSONObject){
                                    keyValue.put(node_key,((JSONObject)jsonParameter).getDoubleValue(entity.getKey()));
                                    ((Map<String,Object>)mapOrList).put(entity.getKey(),((JSONObject)jsonParameter).getDoubleValue(entity.getKey()));
                                }
                                else if(jsonParameter instanceof JSONArray){
                                    if(((JSONArray)jsonParameter).size()>0) {
                                        keyValue.put(node_key,((JSONArray)jsonParameter).getJSONObject(0).getDoubleValue(entity.getKey()));
                                        ((Map<String,Object>)mapOrList).put(entity.getKey(),((JSONArray)jsonParameter).getJSONObject(0).getDoubleValue(entity.getKey()));
                                    }
                                }
                            }
                        }
                        else if(data_type==-1){
                            List entityList=new ArrayList();
                            ((Map<String,Object>)mapOrList).put(entity.getKey(),entityList);
                            keyValue.put(node_key,entityList);

                            if(jsonParameter instanceof JSONObject){
                                JSONArray arr= (JSONArray) ((JSONObject)jsonParameter).get(entity.getKey());
                                if(arr!=null){
                                    for(int i=0;i<arr.size();i++){
                                        Map<String,Object> childMap=new HashMap<>();
                                        entityList.add(childMap);
                                        getInTreeData(entityMap,childMap,arr.get(i),childMap);
                                    }
                                }
                            }
                            else if(jsonParameter instanceof JSONArray){

                            }
                        }
                        else{
                            if(jsonParameter==null){
                                ((Map<String,Object>)mapOrList).put(entity.getKey(),null);
                            }
                            else{
                                if(jsonParameter instanceof JSONObject){
                                    keyValue.put(node_key,((JSONObject)jsonParameter).get(entity.getKey()));
                                    ((Map<String,Object>)mapOrList).put(entity.getKey(),((JSONObject)jsonParameter).get(entity.getKey()));
                                }
                                else if(jsonParameter instanceof JSONArray){

                                    if(((JSONArray)jsonParameter).size()>0){
                                        keyValue.put(node_key,((JSONArray)jsonParameter).getJSONObject(0).get(entity.getKey()));
                                        ((Map<String,Object>)mapOrList).put(entity.getKey(),((JSONArray)jsonParameter).getJSONObject(0).get(entity.getKey()));
                                    }

                                }
                            }
                        }
                    }
                    else if(mapOrList instanceof List){

                    }
                }
                else if(valuation_type==3){
                    if(mapOrList instanceof Map){
                        if(data_type==5){
                            if(jsonParameter==null){
                                ((Map<String,Object>)mapOrList).put(entity.getKey(),null);
                            }
                            else{
                                if(jsonParameter instanceof JSONObject){
                                    keyValue.put(node_key,((JSONObject)jsonParameter).get(entity.getKey()));
                                    ((Map<String,Object>)mapOrList).put(entity.getKey(),((JSONObject)jsonParameter).get(entity.getKey()));
                                }
                                else if(jsonParameter instanceof JSONArray){
                                    keyValue.put(node_key,((JSONArray)jsonParameter).getJSONObject(0).get(entity.getKey()));
                                    ((Map<String,Object>)mapOrList).put(entity.getKey(),((JSONArray)jsonParameter).getJSONObject(0).get(entity.getKey()));
                                }
                            }
                        }
                        else if(data_type==4){
                            if(jsonParameter==null){
                                ((Map<String,Object>)mapOrList).put(entity.getKey(),null);
                            }
                            else{
                                if(jsonParameter instanceof JSONObject){
                                    keyValue.put(node_key,((JSONObject)jsonParameter).getDoubleValue(entity.getKey()));
                                    ((Map<String,Object>)mapOrList).put(entity.getKey(),((JSONObject)jsonParameter).getDoubleValue(entity.getKey()));
                                }
                                else if(jsonParameter instanceof JSONArray){
                                    if(((JSONArray)jsonParameter).size()>0) {
                                        keyValue.put(node_key,((JSONArray)jsonParameter).getJSONObject(0).getDoubleValue(entity.getKey()));
                                        ((Map<String,Object>)mapOrList).put(entity.getKey(),((JSONArray)jsonParameter).getJSONObject(0).getDoubleValue(entity.getKey()));
                                    }
                                }
                            }
                        }
                        else if(data_type==-1){
                            List entityList=new ArrayList();
                            ((Map<String,Object>)mapOrList).put(entity.getKey(),entityList);
                            keyValue.put(node_key,entityList);

                            if(jsonParameter instanceof JSONObject){
                                JSONArray arr= (JSONArray) ((JSONObject)jsonParameter).get(entity.getKey());
                                if(arr!=null){
                                    for(int i=0;i<arr.size();i++){
                                        Map<String,Object> childMap=new HashMap<>();
                                        entityList.add(childMap);
                                        getInTreeData(entityMap,childMap,arr.get(i),childMap);
                                    }
                                }
                            }
                            else if(jsonParameter instanceof JSONArray){

                            }
                        }
                        else{
                            if(jsonParameter==null){
                                ((Map<String,Object>)mapOrList).put(entity.getKey(),null);
                            }
                            else{
                                if(jsonParameter instanceof JSONObject){
                                    keyValue.put(node,((JSONObject)jsonParameter).get(entity.getKey()));
                                    ((Map<String,Object>)mapOrList).put(entity.getKey(),((JSONObject)jsonParameter).get(entity.getKey()));
                                }
                                else if(jsonParameter instanceof JSONArray){

                                    if(((JSONArray)jsonParameter).size()>0){
                                        keyValue.put(node,((JSONArray)jsonParameter).getJSONObject(0).get(entity.getKey()));
                                        ((Map<String,Object>)mapOrList).put(entity.getKey(),((JSONArray)jsonParameter).getJSONObject(0).get(entity.getKey()));
                                    }

                                }
                            }
                        }
                    }
                    else if(mapOrList instanceof List){

                    }
                }

            }
        }
    }
    public static void getOutTree(List<Map<String, Object>> outSettingList,Map<String,Object> saveMateriel,Map<String,Object> keyValue,int k3cloudSave){
        Map<String,Object> outTree=new HashMap<>();
        setParameterToTree(outSettingList,"0",outTree);
        getOutTreeData(outTree,saveMateriel,keyValue,false);
    }
    private static void getOutTreeData(Map<String,Object> tree,Object saveMateriel,Map<String,Object> keyValue,boolean nodeValue){
        Set<Map.Entry<String,Object>> set=tree.entrySet();
        for(Map.Entry<String,Object> entity: set) {
            if(entity.getValue() instanceof Map){
                Map<String,Object> entityMap= (Map<String, Object>) entity.getValue();
                int valuation_type= -2;
                if(entityMap.get("valuation_type")!=null){
                    valuation_type= (int) entityMap.get("valuation_type");
                }
                int data_type=-2;
                if(entityMap.get("data_type")!=null){
                    data_type= (int) entityMap.get("data_type");
                }
                String default_value= (String) entityMap.get("default_value");
                int processing_strategy = 0;
                if(entityMap.get("processing_strategy")!=null){
                    processing_strategy =(int)entityMap.get("processing_strategy");

                }

                if(valuation_type==0){
                    if(data_type==-2){
                        if(saveMateriel instanceof Map){
                            List entityList=new ArrayList();
                            ((Map<String,Object>)saveMateriel).put(entity.getKey(),entityList);

                            for(Map.Entry<String,Object> bl:entityMap.entrySet()){
                                if(bl.getValue() instanceof Map){
                                    Map<String,Object> childMap=new HashMap<>();
                                    entityList.add(childMap);
                                    getOutTreeData((Map<String,Object>)bl.getValue(),childMap,keyValue,nodeValue);
                                }
                            }
                        }
                    }
                    else if(data_type==-1){
                        if(saveMateriel instanceof Map){
                            List entityList=new ArrayList();
                            ((Map<String,Object>)saveMateriel).put(entity.getKey(),entityList);
                            Map<String,Object> childMap=new HashMap<>();
                            entityList.add(childMap);
                            getOutTreeData(entityMap,childMap,keyValue,nodeValue);
                        }
                    }
                    else if(data_type==0){
                        Map<String,Object> childMap=new HashMap<>();
                        ((Map<String,Object>)saveMateriel).put(entity.getKey(),childMap);
                        getOutTreeData(entityMap,childMap,keyValue,false);

                    }
                    else if(data_type==5){
                        if(saveMateriel instanceof Map){
                            ((Map<String,Object>)saveMateriel).put(entity.getKey(),new ArrayList<>());
                        }
                    }
                }
                else if(valuation_type== 1){
                    if(saveMateriel instanceof Map){
                        if(processing_strategy==1){
                            ((Map<String,Object>)saveMateriel).put(entity.getKey(),null);
                            continue;
                        }
                        if(data_type==5){
                            if(default_value==null){
                                ((Map<String,Object>)saveMateriel).put(entity.getKey(),null);
                            }
                            else{
                                JSONObject v=JSONObject.parseObject(default_value);
                                ((Map<String,Object>)saveMateriel).put(entity.getKey(),v.get("value"));
                            }
                        }
                        else if(data_type==4){
                            if(default_value==null){
                                ((Map<String,Object>)saveMateriel).put(entity.getKey(),null);
                            }
                            else{
                                JSONObject v=JSONObject.parseObject(default_value);
                                ((Map<String,Object>)saveMateriel).put(entity.getKey(),v.getDoubleValue("value"));
                            }
                        }
                        else if(data_type==2){
                            if(default_value==null){
                                ((Map<String,Object>)saveMateriel).put(entity.getKey(),null);
                            }
                            else{
                                JSONObject v=JSONObject.parseObject(default_value);
                                ((Map<String,Object>)saveMateriel).put(entity.getKey(),v.getBooleanValue("value"));
                            }
                        }
                        else{
                            if(default_value==null){
                                ((Map<String,Object>)saveMateriel).put(entity.getKey(),null);
                            }
                            else{
                                JSONObject v=JSONObject.parseObject(default_value);
                                ((Map<String,Object>)saveMateriel).put(entity.getKey(),v.get("value"));
                            }
                        }
                    }
                    else if(saveMateriel instanceof List){
                    }
                }
                else if(valuation_type==2){
                    String in_key= (String) entityMap.get("in_key");
                    if(saveMateriel instanceof Map){
                        if(processing_strategy==1){
                            ((Map<String,Object>)saveMateriel).put(entity.getKey(),null);
                            continue;
                        }
                        if(data_type==5){
                            if(keyValue==null){
                                ((Map<String,Object>)saveMateriel).put(entity.getKey(),new ArrayList<>());
                            }
                            else{
                                if(keyValue.containsKey("huaz_options")){
                                    List<Map<String, Object>> options=(List<Map<String, Object>>)keyValue.get("huaz_options");
                                    String plm_source_type_id=null;
                                    for(Map<String,Object> option: options){
                                        if("BOM属性".equals(option.get("plmtype"))){
                                            plm_source_type_id= (String) option.get("plm_source_type_id");
                                            break;
                                        }
                                        else if("采购BOM属性".equals(option.get("plmtype"))){
                                            plm_source_type_id= (String) option.get("plm_source_type_id");
                                            break;
                                        }
                                    }
                                    if(plm_source_type_id!=null){
                                        List<Map<String, Object>> numberList= (List<Map<String, Object>>) keyValue.get(plm_source_type_id);
                                        List<String> numbers=new ArrayList<>();
                                        for(int a=0;a<numberList.size();a++){
                                            numbers.add((String) numberList.get(a).get(in_key));
                                        }
                                        ((Map<String,Object>)saveMateriel).put(entity.getKey(),numbers);
                                    }
                                }
                                else{
                                    Object inObj=keyValue.get(in_key);
                                    if(inObj instanceof String){
                                        List<String> inList=new ArrayList<>();
                                        inList.add((String) inObj);
                                        ((Map<String,Object>)saveMateriel).put(entity.getKey(),inList);
                                    }
                                    else{
                                        ((Map<String,Object>)saveMateriel).put(entity.getKey(),keyValue.get(in_key));
                                    }
                                }

                            }
                        }
                        else if(data_type==4){
                            if(keyValue==null){
                                ((Map<String,Object>)saveMateriel).put(entity.getKey(),null);
                            }
                            else{
                                Object inObj=keyValue.get(in_key);
                                if(inObj instanceof String){
                                    ((Map<String,Object>)saveMateriel).put(entity.getKey(),keyValue.get(in_key));
                                }
                                else{
                                    ((Map<String,Object>)saveMateriel).put(entity.getKey(),keyValue.get(in_key));
                                }
                            }
                        }
                        else if(data_type==2){
                            if(keyValue==null){
                                ((Map<String,Object>)saveMateriel).put(entity.getKey(),null);
                            }
                            else{
                                Object inObj=keyValue.get(in_key);
                                if(inObj instanceof JSONArray){
                                    JSONArray arr= (JSONArray) inObj;
                                    if(arr==null){
                                        ((Map<String,Object>)saveMateriel).put(entity.getKey(),null);
                                    }
                                    else{
                                        if(arr.size()>0){
                                            String booleanStr=arr.getString(0);
                                            if("".equals(booleanStr)==false){
                                                ((Map<String,Object>)saveMateriel).put(entity.getKey(),arr.getBooleanValue(0));
                                            }
                                            else{
                                                ((Map<String,Object>)saveMateriel).put(entity.getKey(),false);
                                            }
                                        }
                                        else{
                                            ((Map<String,Object>)saveMateriel).put(entity.getKey(),null);
                                        }
                                    }
                                }
                                else{
                                    ((Map<String,Object>)saveMateriel).put(entity.getKey(),keyValue.get(in_key));
                                }
                            }
                        }
                        else if(data_type==-1){
                            List entityList=new ArrayList();
                            ((Map<String,Object>)saveMateriel).put(entity.getKey(),entityList);
                            Object objList=keyValue.get(in_key);
                            if(objList instanceof ArrayList){
                                List<Map<String,Object>> arr= (List<Map<String,Object>>) keyValue.get(in_key);
                                for(int i=0;i<arr.size();i++){
                                    Map<String,Object> childMap=new HashMap<>();
                                    entityList.add(childMap);
                                    getOutTreeData(entityMap,childMap,arr.get(i),nodeValue);
                                }
                            }
                            else if(objList instanceof JSONArray){
                                JSONArray arr= (JSONArray) keyValue.get(in_key);
                                for(int i=0;i<arr.size();i++){
                                    Map<String,Object> childMap=new HashMap<>();
                                    entityList.add(childMap);
                                    getOutTreeData(entityMap,childMap,arr.getJSONObject(i),nodeValue);
                                }
                            }
                        }
                        else{
                            if(nodeValue==false){
                                if(keyValue==null){
                                    ((Map<String,Object>)saveMateriel).put(entity.getKey(),null);
                                }
                                else{
                                    Object objValue=keyValue.get(in_key);
                                    if(objValue==null){
                                        ((Map<String,Object>)saveMateriel).put(entity.getKey(),null);
                                    }
                                    else{
                                        if(objValue instanceof JSONArray){
                                            JSONArray objArr = (JSONArray) objValue;
                                            ((Map<String,Object>)saveMateriel).put(entity.getKey(),objArr.get(0));
                                        }
                                        else{
                                            ((Map<String,Object>)saveMateriel).put(entity.getKey(),objValue);
                                        }
                                    }
                                }
                            }
                            else{
                                if(keyValue==null){
                                    ((Map<String,Object>)saveMateriel).put(entity.getKey(),null);
                                }
                                else{
                                    ((Map<String,Object>)saveMateriel).put(entity.getKey(),keyValue.get(entity.getKey()));
                                }
                            }
                        }
                    }

                }
                else if(valuation_type==3){
                    String in_key= (String) entityMap.get("in_key");
                    if(saveMateriel instanceof Map){
                        if(processing_strategy==1){
                            ((Map<String,Object>)saveMateriel).put(entity.getKey(),null);
                            continue;
                        }
                        JSONObject vJson=JSONObject.parseObject(default_value);
                        String template=vJson.getString("value");

                        Map<String,Object> vakue= (Map<String,Object>) keyValue.get(in_key);
                        if(vakue!=null){
                            String message=replaceVariables(template,vakue);
                            ((Map<String,Object>)saveMateriel).put(entity.getKey(),message);
                        }

                    }

                }

            }
        }
    }
    public static String replaceVariables(String template, Map<String, Object> variables) {
        Pattern pattern = Pattern.compile("\\$\\{(\\w+)\\}");
        Matcher matcher = pattern.matcher(template);
        StringBuffer buffer = new StringBuffer();

        while (matcher.find()) {
            String key = matcher.group(1);
            Object obj=variables.getOrDefault(key, matcher.group());
            if(obj instanceof String){
                String replacement = (String) obj;
                matcher.appendReplacement(buffer, replacement);
            }
            else if(obj instanceof Long){
                String replacement =Long.toString((Long) obj);
                matcher.appendReplacement(buffer, replacement);
            }
            else if(obj instanceof Double){
                String replacement =Double.toString((Double) obj);
                matcher.appendReplacement(buffer, replacement);
            }
            else if(obj instanceof Float){
                String replacement =Float.toString((Float) obj);
                matcher.appendReplacement(buffer, replacement);
            }
        }
        matcher.appendTail(buffer);

        return buffer.toString();
    }

}
